package cn.com.infcn.monitor.server;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.infcn.monitor.secure.SecretTokenMgr;
import cn.com.infcn.monitor.util.IFCMinitorConstanst;

/**
 * 监控服务启动类
 * @author jijs
 *
 */
public class MonitorServer {
	
	private final static Logger logger = LoggerFactory.getLogger(MonitorServer.class);
	
	private static MonitorServer monitorServer = null;  
    private SocketAcceptor acceptor = new NioSocketAcceptor();  
    private DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();  
    public static final int DEFAULT_SERVER_PORT = 56788;
  
    public static MonitorServer getInstances() {  
        if (null == monitorServer) {  
        	synchronized (MonitorServer.class) {
        		if (null == monitorServer) { 
        			monitorServer = new MonitorServer();
        		}
			}
        }
        return monitorServer;  
    }  
  
    private MonitorServer() {  
    	initParam();
    	initServer();
    }
    
    private void initParam() {
    	IMonitorConfig conf = IMonitorConfig.getInstance();
		IFCMinitorConstanst.JMXURL = conf.getStringValue("jmx.url");
	}

	public void initServer(){
		IMonitorConfig conf = IMonitorConfig.getInstance();
    	
        chain.addLast("codec", new ProtocolCodecFilter(  
                new ObjectSerializationCodecFactory()));  
        chain.addLast("threadPool", new ExecutorFilter(conf.getIntValue("httpclient.max.thread")));
        
        if (conf.getBooleanValue("mina.logging.enable", true)) {
        	logger.info("Add logging filter...");
        	chain.addLast("logger", new LoggingFilter());
        }
        
        acceptor.setHandler(ServerHandler.getInstances());  
        try {  
        	int bindPort = conf.getIntValue("monitor.listen.port", DEFAULT_SERVER_PORT);
            acceptor.bind(new InetSocketAddress(bindPort));  
        } catch (IOException e) {  
            e.printStackTrace();  
        }
        
        int timeout = conf.getIntValue("monitor.token.timeout", 60*60);
        SecretTokenMgr tokenMgr = SecretTokenMgr.getInstance();
        tokenMgr.start(timeout);
        
        
        try {
			Runtime.getRuntime().addShutdownHook(new Thread() {
				public void run() {
					logger.info("monitor shutdown");
					acceptor.unbind();
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
    }

	public static void main(String[] args) {
		MonitorServer.getInstances();
	}
}
